<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<LINK REL=STYLESHEET TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
<META NAME="GENERATOR" CONTENT="Java2HTML Version 1.5">
<TITLE>czestmyr.jjsched.TimeHandler (Java2HTML)</TITLE>
</HEAD>
<BODY><TABLE id="Header" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td colspan="2" width="33%">&nbsp;</td>
<td align="center" colspan="2" width="33%">
<font size="4">TimeHandler.java</font>
</td>
<td align="right" colspan="2" width="33%">&nbsp;</td>
</tr>
</TABLE>
<pre ID="Classes">
<A NAME="1"></A><FONT ID="MultiLineComment">/*  This file is a part of JJSched source code
<A NAME="2"></A>    JJSched - Java Jabber Scheduler - a simple Jabber scheduling application
<A NAME="3"></A>    Copyright (C) 2008 Cestmir "CZestmyr" Houska
<A NAME="4"></A>
<A NAME="5"></A>    This program is free software: you can redistribute it and/or modify
<A NAME="6"></A>    it under the terms of the GNU General Public License as published by
<A NAME="7"></A>    the Free Software Foundation, either version 3 of the License, or
<A NAME="8"></A>    (at your option) any later version.
<A NAME="9"></A>
<A NAME="10"></A>    This program is distributed in the hope that it will be useful,
<A NAME="11"></A>    but WITHOUT ANY WARRANTY; without even the implied warranty of
<A NAME="12"></A>    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
<A NAME="13"></A>    GNU General Public License for more details.
<A NAME="14"></A>
<A NAME="15"></A>    You should have received a copy of the GNU General Public License
<A NAME="16"></A>    along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt; */</FONT>
<A NAME="17"></A>
<A NAME="18"></A><FONT ID="Package">package</FONT> czestmyr.jjsched;
<A NAME="19"></A>
<A NAME="20"></A><FONT ID="Import">import</FONT> java.util.*;
<A NAME="21"></A><FONT ID="Import">import</FONT> java.text.*;
<A NAME="22"></A>
<A NAME="23"></A><FONT ID="FormalComment">/**
<A NAME="24"></A> * Handles the manipulation with time differences and time expressions.
<A NAME="25"></A> * Also provides some methods for parsing various time expression
<A NAME="26"></A> */</FONT>
<A NAME="27"></A><FONT ID="Public">public</FONT> <FONT ID="Class">class</FONT> TimeHandler{
<A NAME="28"></A>    <FONT ID="FormalComment">/**
<A NAME="29"></A>     * Get actual time, formatted into a string.
<A NAME="30"></A>     *
<A NAME="31"></A>     * @return  The string representation of the actual server time
<A NAME="32"></A>     */</FONT>
<A NAME="33"></A>    <FONT ID="Public">public</FONT> String getFormattedTime(){
<A NAME="34"></A>        cal = Calendar.getInstance();
<A NAME="35"></A>        <FONT ID="Return">return</FONT> readableTimeFormat.format(cal.getTime());
<A NAME="36"></A>    }
<A NAME="37"></A>
<A NAME="38"></A>    <FONT ID="FormalComment">/**
<A NAME="39"></A>     * Get the time specified by the timestamp into a string.
<A NAME="40"></A>     *
<A NAME="41"></A>     * @param   timestamp   The timestamp of the time that should be formatted into a string
<A NAME="42"></A>     * @return          The string representation of the given timestamp
<A NAME="43"></A>     */</FONT>
<A NAME="44"></A>    <FONT ID="Public">public</FONT> String getFormattedTime(<FONT ID="Long">long</FONT> timestamp){
<A NAME="45"></A>        <FONT ID="Return">return</FONT> readableTimeFormat.format(timestamp);
<A NAME="46"></A>    }
<A NAME="47"></A>
<A NAME="48"></A>    <FONT ID="FormalComment">/**
<A NAME="49"></A>     * Get the time specified by the timestamp in an SQL-compatible string representation
<A NAME="50"></A>     *
<A NAME="51"></A>     * @param   timestamp       The timestamp of the time that should be converted to SQL string
<A NAME="52"></A>     * @return                  The string representation of the timestamp in SQL-compatible format
<A NAME="53"></A>     */</FONT>
<A NAME="54"></A>    <FONT ID="Public">public</FONT> String getSqlFormattedTime(<FONT ID="Long">long</FONT> timestamp){
<A NAME="55"></A>        <FONT ID="Return">return</FONT> sqlTimeFormat.format(timestamp);
<A NAME="56"></A>    }
<A NAME="57"></A>
<A NAME="58"></A>    <FONT ID="FormalComment">/**
<A NAME="59"></A>     * Get the given time offset, formatted in a string
<A NAME="60"></A>     *
<A NAME="61"></A>     * @param   timestamp   The timestamp, containing the offset
<A NAME="62"></A>     * @return          The offset, nicely formatted into a string
<A NAME="63"></A>     */</FONT>
<A NAME="64"></A>    <FONT ID="Public">public</FONT> String getFormattedOffset(<FONT ID="Long">long</FONT> timestamp){
<A NAME="65"></A>        <FONT ID="Boolean">boolean</FONT> positive = <FONT ID="True">true</FONT>;
<A NAME="66"></A>        <FONT ID="If">if</FONT> (timestamp &lt; <FONT ID="IntegerLiteral">0</FONT>) {
<A NAME="67"></A>            positive = <FONT ID="False">false</FONT>;
<A NAME="68"></A>            timestamp = -timestamp;
<A NAME="69"></A>        }
<A NAME="70"></A>        <FONT ID="SingleLineComment">//I don't know why this has to be here, but it works :(
<A NAME="71"></A></FONT>        timestamp -= timeDiffValues[<FONT ID="IntegerLiteral">2</FONT>];
<A NAME="72"></A>
<A NAME="73"></A>        SimpleDateFormat sdf = <FONT ID="New">new</FONT> SimpleDateFormat(<FONT ID="StringLiteral">"H:mm:ss"</FONT>);
<A NAME="74"></A>        <FONT ID="If">if</FONT> (positive)
<A NAME="75"></A>            <FONT ID="Return">return</FONT> <FONT ID="StringLiteral">"+ "</FONT>+sdf.format(timestamp);
<A NAME="76"></A>        <FONT ID="Else">else</FONT>
<A NAME="77"></A>            <FONT ID="Return">return</FONT> <FONT ID="StringLiteral">"- "</FONT>+sdf.format(timestamp);
<A NAME="78"></A>    }
<A NAME="79"></A>
<A NAME="80"></A>    <FONT ID="FormalComment">/**
<A NAME="81"></A>     * Get actual server time in milliseconds
<A NAME="82"></A>     *
<A NAME="83"></A>     * @return  The actual server time in milliseconds
<A NAME="84"></A>     */</FONT>
<A NAME="85"></A>    <FONT ID="Public">public</FONT> <FONT ID="Long">long</FONT> getLongTime(){
<A NAME="86"></A>        cal = Calendar.getInstance();
<A NAME="87"></A>
<A NAME="88"></A>        <FONT ID="Return">return</FONT> cal.getTimeInMillis();
<A NAME="89"></A>    }
<A NAME="90"></A>
<A NAME="91"></A>    <FONT ID="FormalComment">/**
<A NAME="92"></A>     * Parse time, given as a string time expression (see user documentation).
<A NAME="93"></A>     * The time is in a local time, that differs from the time of the server by timeOffset.
<A NAME="94"></A>     * This functions thus decreases the returned value by timeOffset.
<A NAME="95"></A>     *
<A NAME="96"></A>     * @param   toParse     The string that contains the time expression
<A NAME="97"></A>     * @param   timeOffset  Difference between the local time and server time (LT - ST)
<A NAME="98"></A>     * @throws  Exception       In case if parse error
<A NAME="99"></A>     * @return                  Representation of the time in milliseconds
<A NAME="100"></A>     */</FONT>
<A NAME="101"></A>    <FONT ID="Public">public</FONT> <FONT ID="Long">long</FONT> parseToServerTime(String toParse, <FONT ID="Long">long</FONT> timeOffset) <FONT ID="Throws">throws</FONT> Exception{
<A NAME="102"></A>        <FONT ID="Long">long</FONT> time = <FONT ID="IntegerLiteral">0</FONT>;
<A NAME="103"></A>
<A NAME="104"></A>        <FONT ID="SingleLineComment">//Divide toParse string into origin[+plus][-minus]
<A NAME="105"></A></FONT>        String minus = <FONT ID="Null">null</FONT>;
<A NAME="106"></A>        String plus = <FONT ID="Null">null</FONT>;
<A NAME="107"></A>        String origin = <FONT ID="Null">null</FONT>;
<A NAME="108"></A>
<A NAME="109"></A>        <FONT ID="Int">int</FONT> p = toParse.indexOf(<FONT ID="CharacerLiteral">'+'</FONT>);
<A NAME="110"></A>        <FONT ID="Int">int</FONT> m = toParse.indexOf(<FONT ID="CharacerLiteral">'-'</FONT>);
<A NAME="111"></A>        <FONT ID="If">if</FONT> (m != -<FONT ID="IntegerLiteral">1</FONT> &amp;&amp; m != toParse.length()-<FONT ID="IntegerLiteral">1</FONT>) {
<A NAME="112"></A>            minus = toParse.substring(m+<FONT ID="IntegerLiteral">1</FONT>,toParse.length());
<A NAME="113"></A>        }
<A NAME="114"></A>        <FONT ID="If">if</FONT> (p != -<FONT ID="IntegerLiteral">1</FONT> &amp;&amp; p != toParse.length()-<FONT ID="IntegerLiteral">1</FONT>) {
<A NAME="115"></A>            <FONT ID="If">if</FONT> (m != -<FONT ID="IntegerLiteral">1</FONT>) {
<A NAME="116"></A>                <FONT ID="If">if</FONT> (m &gt; p) {
<A NAME="117"></A>                    plus = toParse.substring(p+<FONT ID="IntegerLiteral">1</FONT>,m);
<A NAME="118"></A>                } <FONT ID="Else">else</FONT>
<A NAME="119"></A>                    <FONT ID="Throw">throw</FONT> <FONT ID="New">new</FONT> ParseException(<FONT ID="StringLiteral">"Relative time specifier error - decreasing should be AFTER increasing"</FONT>, m);
<A NAME="120"></A>            } <FONT ID="Else">else</FONT> {
<A NAME="121"></A>                plus = toParse.substring(p+<FONT ID="IntegerLiteral">1</FONT>,toParse.length());
<A NAME="122"></A>            }
<A NAME="123"></A>        }
<A NAME="124"></A>        <FONT ID="If">if</FONT> (p != -<FONT ID="IntegerLiteral">1</FONT>) {
<A NAME="125"></A>            origin = toParse.substring(<FONT ID="IntegerLiteral">0</FONT>,p);
<A NAME="126"></A>        } <FONT ID="Else">else</FONT> <FONT ID="If">if</FONT> (m != -<FONT ID="IntegerLiteral">1</FONT>) {
<A NAME="127"></A>            origin = toParse.substring(<FONT ID="IntegerLiteral">0</FONT>,m);
<A NAME="128"></A>        } <FONT ID="Else">else</FONT> origin = toParse;
<A NAME="129"></A>
<A NAME="130"></A>        origin = StringParser.beautifyString(origin);
<A NAME="131"></A>
<A NAME="132"></A>        <FONT ID="SingleLineComment">//Parse the three parts of the time expression
<A NAME="133"></A></FONT>        <FONT ID="If">if</FONT>(!origin.equals(<FONT ID="StringLiteral">""</FONT>))
<A NAME="134"></A>            time = parseTime(origin, timeOffset);
<A NAME="135"></A>        <FONT ID="Else">else</FONT> time = parseTime(<FONT ID="StringLiteral">"now"</FONT>, timeOffset);
<A NAME="136"></A>        time += parseTimeDiff(plus);
<A NAME="137"></A>        time -= parseTimeDiff(minus);
<A NAME="138"></A>
<A NAME="139"></A>        <FONT ID="SingleLineComment">//Subtract the time offset
<A NAME="140"></A></FONT>        time -= timeOffset;
<A NAME="141"></A>
<A NAME="142"></A>        <FONT ID="SingleLineComment">//Return the correct server time
<A NAME="143"></A></FONT>        <FONT ID="Return">return</FONT> time;
<A NAME="144"></A>    }
<A NAME="145"></A>
<A NAME="146"></A>    <FONT ID="FormalComment">/**
<A NAME="147"></A>     * Parse the given string as a timediff string as defined in syntax of time specifiers
<A NAME="148"></A>     *
<A NAME="149"></A>     * @param   str The string to be parsed
<A NAME="150"></A>     * @return      The representation of the timediff string in miliseconds
<A NAME="151"></A>     * @throws  Exception   In case of parse error
<A NAME="152"></A>     */</FONT>
<A NAME="153"></A>    <FONT ID="Public">public</FONT> <FONT ID="Long">long</FONT> parseTimeDiff(String str) <FONT ID="Throws">throws</FONT> Exception{
<A NAME="154"></A>        <FONT ID="Long">long</FONT> time = <FONT ID="IntegerLiteral">0</FONT>;
<A NAME="155"></A>        <FONT ID="If">if</FONT> (str == <FONT ID="Null">null</FONT>) <FONT ID="Return">return</FONT> <FONT ID="IntegerLiteral">0</FONT>;
<A NAME="156"></A>
<A NAME="157"></A>        str = StringParser.beautifyString(str);
<A NAME="158"></A>        String[] stringArray = str.split(<FONT ID="StringLiteral">"\\s+"</FONT>);
<A NAME="159"></A>        <FONT ID="Boolean">boolean</FONT> isNumber = <FONT ID="True">true</FONT>;
<A NAME="160"></A>        <FONT ID="Int">int</FONT> number = <FONT ID="IntegerLiteral">0</FONT>;
<A NAME="161"></A>
<A NAME="162"></A>        <FONT ID="SingleLineComment">//Go through all the tokens of the timediff expression
<A NAME="163"></A></FONT>        <FONT ID="For">for</FONT> (<FONT ID="Int">int</FONT> i = <FONT ID="IntegerLiteral">0</FONT>; i &lt; stringArray.length; ++i){
<A NAME="164"></A>            <FONT ID="SingleLineComment">//If we expect a number, try to parse it
<A NAME="165"></A></FONT>            <FONT ID="If">if</FONT> (isNumber) { 
<A NAME="166"></A>                <FONT ID="Try">try</FONT> {
<A NAME="167"></A>                    number = Integer.decode(stringArray[i]).intValue();
<A NAME="168"></A>                } <FONT ID="Catch">catch</FONT> (Exception e) {
<A NAME="169"></A>                    <FONT ID="If">if</FONT> (stringArray[i].equals(<FONT ID="StringLiteral">""</FONT>)) stringArray[i] = <FONT ID="StringLiteral">"nothing"</FONT>;
<A NAME="170"></A>                    <FONT ID="Throw">throw</FONT> <FONT ID="New">new</FONT> Exception(<FONT ID="StringLiteral">"Number expected, but "</FONT>+stringArray[i]+<FONT ID="StringLiteral">" found."</FONT>);
<A NAME="171"></A>                }
<A NAME="172"></A>            <FONT ID="SingleLineComment">//Else multiply the previous number with the corresponding number of milliseconds
<A NAME="173"></A></FONT>            <FONT ID="SingleLineComment">// (e.g.: 2 hours -&gt; 2 * 3600000)
<A NAME="174"></A></FONT>            } <FONT ID="Else">else</FONT> {
<A NAME="175"></A>                <FONT ID="Int">int</FONT> j;
<A NAME="176"></A>                <FONT ID="For">for</FONT> (j = <FONT ID="IntegerLiteral">0</FONT>; j &lt; timeDiffNum; ++j){
<A NAME="177"></A>                    <FONT ID="If">if</FONT> (timeDiffStrings[j].equals(stringArray[i])) {
<A NAME="178"></A>                        time += number * timeDiffValues[j];
<A NAME="179"></A>                        <FONT ID="Break">break</FONT>;
<A NAME="180"></A>                    }
<A NAME="181"></A>                }
<A NAME="182"></A>                <FONT ID="SingleLineComment">//Unknown time difference specifier
<A NAME="183"></A></FONT>                <FONT ID="If">if</FONT> (j == timeDiffNum) <FONT ID="Throw">throw</FONT> <FONT ID="New">new</FONT> Exception(<FONT ID="StringLiteral">"Unknown time difference specifier: "</FONT>+stringArray[i]);
<A NAME="184"></A>                number = <FONT ID="IntegerLiteral">0</FONT>;
<A NAME="185"></A>            }
<A NAME="186"></A>            isNumber = !isNumber;
<A NAME="187"></A>        }
<A NAME="188"></A>        <FONT ID="If">if</FONT> (!isNumber) <FONT ID="Throw">throw</FONT> <FONT ID="New">new</FONT> Exception(<FONT ID="StringLiteral">"Time difference specifier expected after "</FONT>+number);
<A NAME="189"></A>
<A NAME="190"></A>        <FONT ID="Return">return</FONT> time;
<A NAME="191"></A>    }
<A NAME="192"></A>
<A NAME="193"></A>    <FONT ID="FormalComment">/**
<A NAME="194"></A>     * Parse the given string as a time origin expression.
<A NAME="195"></A>     * The time has to be expressed in local time (client time), so that relative time specifiers
<A NAME="196"></A>     * such as now or tomorrow work correctly
<A NAME="197"></A>     *
<A NAME="198"></A>     * @param   str The string to be parsed
<A NAME="199"></A>     * @param   offset  The user time offset
<A NAME="200"></A>     * @return      The representation of the time origin in milliseconds
<A NAME="201"></A>     * @throws  Exception   In case of parse error
<A NAME="202"></A>     */</FONT>
<A NAME="203"></A>    <FONT ID="Private">private</FONT> <FONT ID="Long">long</FONT> parseTime(String str, <FONT ID="Long">long</FONT> offset) <FONT ID="Throws">throws</FONT> Exception{
<A NAME="204"></A>        <FONT ID="Long">long</FONT> time = offset;
<A NAME="205"></A>        <FONT ID="If">if</FONT> (str == <FONT ID="Null">null</FONT>) <FONT ID="Return">return</FONT> <FONT ID="IntegerLiteral">0</FONT>;
<A NAME="206"></A>        <FONT ID="Int">int</FONT> a = str.indexOf(<FONT ID="CharacerLiteral">'/'</FONT>);
<A NAME="207"></A>        String timeStr = <FONT ID="Null">null</FONT>;
<A NAME="208"></A>        String day = <FONT ID="Null">null</FONT>;
<A NAME="209"></A>
<A NAME="210"></A>        cal = Calendar.getInstance();
<A NAME="211"></A>
<A NAME="212"></A>        <FONT ID="SingleLineComment">//If there's a '/' character, parse the string before it as a date
<A NAME="213"></A></FONT>        <FONT ID="If">if</FONT> (a != -<FONT ID="IntegerLiteral">1</FONT>) {
<A NAME="214"></A>            day = str.substring(<FONT ID="IntegerLiteral">0</FONT>,a);
<A NAME="215"></A>            <FONT ID="If">if</FONT> (a != str.length())
<A NAME="216"></A>                timeStr = str.substring(a+<FONT ID="IntegerLiteral">1</FONT>, str.length());
<A NAME="217"></A>
<A NAME="218"></A>            <FONT ID="SingleLineComment">//count the number of dots in the pattern (one or two)
<A NAME="219"></A></FONT>            <FONT ID="Int">int</FONT> dotPosition = day.indexOf(<FONT ID="CharacerLiteral">'.'</FONT>);
<A NAME="220"></A>            dotPosition = day.indexOf(<FONT ID="CharacerLiteral">'.'</FONT>, dotPosition+<FONT ID="IntegerLiteral">1</FONT>);
<A NAME="221"></A>            <FONT ID="Try">try</FONT> {
<A NAME="222"></A>                SimpleDateFormat sdf = <FONT ID="New">new</FONT> SimpleDateFormat(<FONT ID="StringLiteral">"dd.MM.yyyy"</FONT>);
<A NAME="223"></A>                <FONT ID="SingleLineComment">//if there are two or more dots, parse the day as dd.MM.yyyy
<A NAME="224"></A></FONT>                <FONT ID="If">if</FONT> (dotPosition != -<FONT ID="IntegerLiteral">1</FONT>) {
<A NAME="225"></A>                    time += sdf.parse(day).getTime();
<A NAME="226"></A>                <FONT ID="SingleLineComment">//if there are less than two dots, parse day as dd.MM
<A NAME="227"></A></FONT>                } <FONT ID="Else">else</FONT> {
<A NAME="228"></A>                    time += sdf.parse(day+<FONT ID="StringLiteral">"."</FONT>+cal.get(Calendar.YEAR)).getTime();
<A NAME="229"></A>                }
<A NAME="230"></A>            } <FONT ID="Catch">catch</FONT> (ParseException e) {
<A NAME="231"></A>                <FONT ID="Throw">throw</FONT> <FONT ID="New">new</FONT> ParseException(<FONT ID="StringLiteral">"Could not parse the date before '/' character"</FONT>, <FONT ID="IntegerLiteral">0</FONT>);
<A NAME="232"></A>            }
<A NAME="233"></A>        <FONT ID="SingleLineComment">//Else set the date to today
<A NAME="234"></A></FONT>        } <FONT ID="Else">else</FONT> {
<A NAME="235"></A>            timeStr = str;
<A NAME="236"></A>
<A NAME="237"></A>            <FONT ID="SingleLineComment">//Check, whether the expressions are not literals
<A NAME="238"></A></FONT>            <FONT ID="If">if</FONT> (str.equals(<FONT ID="StringLiteral">"now"</FONT>)){
<A NAME="239"></A>                <FONT ID="SingleLineComment">//return actual time
<A NAME="240"></A></FONT>                <FONT ID="Return">return</FONT> time + cal.getTimeInMillis();
<A NAME="241"></A>            } <FONT ID="Else">else</FONT> <FONT ID="If">if</FONT> (str.equals(<FONT ID="StringLiteral">"tomorrow"</FONT>)){
<A NAME="242"></A>                <FONT ID="SingleLineComment">//now + 24*60*60*1000 milliseconds (one day)
<A NAME="243"></A></FONT>                <FONT ID="Return">return</FONT> time + cal.getTimeInMillis() + <FONT ID="IntegerLiteral">86400000</FONT>;
<A NAME="244"></A>            } <FONT ID="Else">else</FONT> <FONT ID="If">if</FONT> (str.equals(<FONT ID="StringLiteral">"next week"</FONT>)){
<A NAME="245"></A>                <FONT ID="SingleLineComment">//now + 7*24*60*60*1000 milliseconds (seven days)
<A NAME="246"></A></FONT>                <FONT ID="Return">return</FONT> time + cal.getTimeInMillis() + <FONT ID="IntegerLiteral">604800000</FONT>;
<A NAME="247"></A>            } <FONT ID="Else">else</FONT> {
<A NAME="248"></A>                <FONT ID="SingleLineComment">//The time will contain the local time of the client now
<A NAME="249"></A></FONT>                time += cal.getTimeInMillis();
<A NAME="250"></A>                <FONT ID="SingleLineComment">//Truncate the value in time down to whole days
<A NAME="251"></A></FONT>                time = time / timeDiffValues[<FONT ID="IntegerLiteral">3</FONT>] * timeDiffValues[<FONT ID="IntegerLiteral">3</FONT>];
<A NAME="252"></A>            }
<A NAME="253"></A>        }
<A NAME="254"></A>
<A NAME="255"></A>        <FONT ID="SingleLineComment">//Now we have the date, let's parse the time!
<A NAME="256"></A></FONT>        <FONT ID="If">if</FONT> (timeStr == <FONT ID="Null">null</FONT>) <FONT ID="Throw">throw</FONT> <FONT ID="New">new</FONT> ParseException(<FONT ID="StringLiteral">"Missing time after the '/' character"</FONT>, a);
<A NAME="257"></A>
<A NAME="258"></A>        <FONT ID="SingleLineComment">//count the number of double dots
<A NAME="259"></A></FONT>        <FONT ID="Int">int</FONT> ddPosition = timeStr.indexOf(<FONT ID="CharacerLiteral">':'</FONT>);
<A NAME="260"></A>        ddPosition = timeStr.indexOf(<FONT ID="CharacerLiteral">':'</FONT>, ddPosition+<FONT ID="IntegerLiteral">1</FONT>);
<A NAME="261"></A>
<A NAME="262"></A>        <FONT ID="Try">try</FONT> {
<A NAME="263"></A>            <FONT ID="SingleLineComment">//If we have two or more double dots, parse the time as HH:mm:ss
<A NAME="264"></A></FONT>            <FONT ID="If">if</FONT> (ddPosition != -<FONT ID="IntegerLiteral">1</FONT>) {
<A NAME="265"></A>                SimpleDateFormat sdf = <FONT ID="New">new</FONT> SimpleDateFormat(<FONT ID="StringLiteral">"HH:mm:ss"</FONT>);
<A NAME="266"></A>                time += sdf.parse(timeStr).getTime();
<A NAME="267"></A>            <FONT ID="SingleLineComment">//else, parse the time as MM:mm
<A NAME="268"></A></FONT>            } <FONT ID="Else">else</FONT> {
<A NAME="269"></A>                SimpleDateFormat sdf = <FONT ID="New">new</FONT> SimpleDateFormat(<FONT ID="StringLiteral">"HH:mm"</FONT>);
<A NAME="270"></A>                time += sdf.parse(timeStr).getTime();
<A NAME="271"></A>            }
<A NAME="272"></A>        } <FONT ID="Catch">catch</FONT> (Exception e) {
<A NAME="273"></A>            <FONT ID="Throw">throw</FONT> <FONT ID="New">new</FONT> ParseException(<FONT ID="StringLiteral">"Could not parse the time after '/' character"</FONT>, a);
<A NAME="274"></A>        }
<A NAME="275"></A>
<A NAME="276"></A>        <FONT ID="SingleLineComment">//We should have the whole time origin expression parsed now, return the time
<A NAME="277"></A></FONT>        <FONT ID="Return">return</FONT> time;
<A NAME="278"></A>    }
<A NAME="279"></A>
<A NAME="280"></A>    <FONT ID="SingleLineComment">//Date formats used when parsing
<A NAME="281"></A></FONT>    <FONT ID="Private">private</FONT> SimpleDateFormat sqlTimeFormat = <FONT ID="New">new</FONT> SimpleDateFormat(<FONT ID="StringLiteral">"yyMMddHHmmss"</FONT>);
<A NAME="282"></A>    <FONT ID="Private">private</FONT> SimpleDateFormat readableTimeFormat =  <FONT ID="New">new</FONT> SimpleDateFormat(<FONT ID="StringLiteral">"dd.MM.yyyy/HH:mm:ss"</FONT>);
<A NAME="283"></A>
<A NAME="284"></A>    <FONT ID="SingleLineComment">//Helper calendar variables
<A NAME="285"></A></FONT>    <FONT ID="Private">private</FONT> Calendar cal = <FONT ID="Null">null</FONT>;
<A NAME="286"></A>    <FONT ID="Private">private</FONT> Calendar remoteCal = <FONT ID="Null">null</FONT>;
<A NAME="287"></A>
<A NAME="288"></A>    <FONT ID="SingleLineComment">//Strings representing different time intervals, used in timediffs
<A NAME="289"></A></FONT>    <FONT ID="Private">private</FONT> <FONT ID="Int">int</FONT> timeDiffNum = <FONT ID="IntegerLiteral">5</FONT>;
<A NAME="290"></A>    <FONT ID="Private">private</FONT> String[] timeDiffStrings = {<FONT ID="StringLiteral">"seconds"</FONT>, <FONT ID="StringLiteral">"minutes"</FONT>, <FONT ID="StringLiteral">"hours"</FONT>, <FONT ID="StringLiteral">"days"</FONT>, <FONT ID="StringLiteral">"weeks"</FONT>};
<A NAME="291"></A>    <FONT ID="Private">private</FONT> <FONT ID="Long">long</FONT>[] timeDiffValues = {<FONT ID="IntegerLiteral">1000</FONT>, <FONT ID="IntegerLiteral">60000</FONT>, <FONT ID="IntegerLiteral">3600000</FONT>, <FONT ID="IntegerLiteral">86400000</FONT>, <FONT ID="IntegerLiteral">604800000</FONT>};
<A NAME="292"></A>}
<A NAME="293"></A></pre>
</BODY>
</HTML>